/**
 * Universidade Federal de Campina Grande - UFCG
 * Departamento de Sistemas e Computação - DSC
 * Disciplina: Compiladores
 * Professor: Marcus Salerno
 * 
 * Projeto da Disciplina - Analisador Lexico
 * 
 *  
 * Contributors:
 * Arthur
 * Carolina
 * Saulo
 * 
 */
package util;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class TabelaDeSimbolos {

	/**
	 * The code of a string.
	 */
	public static final int STRING_CODE = 27;
	
	public static final int COMENTARIO_CODE = 23;

	public static final int COMENTARIO_FECHA_CODE = 13;
	

	private List<Simbolo> listaDeSimbolos;
	private Map<String,Integer> operadores;
	private Map<String,Integer> delimitadores;
	private Map<String, Integer> marcasDePontuacao;
	private Map<String, Integer> palavrasReservadas;
	
	/**
	 * Construtor
	 */
	public TabelaDeSimbolos() {		
		this.listaDeSimbolos = new LinkedList<Simbolo>();
		this.operadores = new HashMap<String, Integer>();
		this.delimitadores = new HashMap<String, Integer>();
		this.marcasDePontuacao = new HashMap<String, Integer>();
		this.palavrasReservadas = new HashMap<String, Integer>();
		this.operadoresMap();
		this.delimitadoresMapa();
		this.pontuacaoMapa();
		this.palavrasReservadasMapa();
	}
	
	/**
	 * 
	 * 
	 * @param symbol
	 */
	public void add(Simbolo symbol) {
		this.listaDeSimbolos.add(symbol);
	}
	
	/**
	 * 
	 * 
	 * @param symbolAsString
	 * @return
	 */
	public boolean contains(String symbolAsString) {
        for (Simbolo symbol : listaDeSimbolos) {
            if (symbol.getSimbolo().equals(symbolAsString)) {
                return true;
            }
        }
        return false;
	}

	public Simbolo getSimbolo(String symbol){
		for (Simbolo s : listaDeSimbolos) {			
			if ((s.getSimbolo().equalsIgnoreCase(symbol))) {
				return s;
			}
		}
		return null;
	}
	
	
	/**
	 * 
	 * 
	 * @param string
	 * @return
	 */
	public boolean ehOperator(String string) {
		return this.operadores.containsKey(string);
	}

	/**
	 * 
	 * @param string
	 * @return
	 */
	public boolean ehDelimitador(String string) {
		return this.delimitadores.containsKey(string);
	}
	
	/**
	 * 
	 * @param string
	 * @return
	 */
	public boolean ehMarcaDePontuacao(String string) {		
		return this.marcasDePontuacao.containsKey(string);
	}
	
	/**
	 * 
	 * @param string
	 * @return
	 */
	public boolean ehPalavraReservada(String string) {
		return this.palavrasReservadas.containsKey(string);
	}
	
	/**
	 * 
	 * @param reservada
	 * @return the code
	 */
	public int getCodigoPalavraReservada(String reservada) {
		return this.palavrasReservadas.get(reservada);
	}

	/**
	 * 
	 * @param symbolString
	 * @return the code
	 */
	public int getCodigo(String symbolString) {
		int returnValue = -1;
		if (this.operadores.containsKey(symbolString)) {
			returnValue = this.operadores.get(symbolString);
		} else if (this.delimitadores.containsKey(symbolString)) {
			returnValue = this.delimitadores.get(symbolString);
		} else if (this.marcasDePontuacao.containsKey(symbolString)) {
			returnValue = this.marcasDePontuacao.get(symbolString);
		} else if (this.palavrasReservadas.containsKey(symbolString)) {
			returnValue = this.palavrasReservadas.get(symbolString);
		}
		return returnValue;
	}
	
	/**
	 */
	private void operadoresMap() {
		this.operadores.put("+",11);
		this.operadores.put("-",12);
		this.operadores.put("*",13);
		this.operadores.put("/",14);
		this.operadores.put("=",15);	
		this.operadores.put("<>",16);
		this.operadores.put("<",17);
		this.operadores.put(">",18);
		this.operadores.put(">=",19);
		this.operadores.put("<=",20);
		this.operadores.put(":=",21);
	}

	/**
	 */
	private void delimitadoresMapa() {
		this.delimitadores.put("(", 23);
		this.delimitadores.put(")", 24);
		this.delimitadores.put("[", 25);
		this.delimitadores.put("]", 26);
		this.delimitadores.put("'", 27);		
	}
	
	/**
	 */
	private void palavrasReservadasMapa() {		
		this.palavrasReservadas.put("call", 40);
		this.palavrasReservadas.put("vetor", 41);
		this.palavrasReservadas.put("comeco", 42);
		this.palavrasReservadas.put("const", 43);
		this.palavrasReservadas.put("faca", 44);
		this.palavrasReservadas.put("senao", 45);
		this.palavrasReservadas.put("fim", 46);
		this.palavrasReservadas.put("para", 47);
		this.palavrasReservadas.put("funcao", 48);
		this.palavrasReservadas.put("se", 49);
		this.palavrasReservadas.put("inteiro", 50);
		this.palavrasReservadas.put("not", 51);
		this.palavrasReservadas.put("de", 52);
		this.palavrasReservadas.put("procedimento", 53);
		this.palavrasReservadas.put("programa", 54);
		this.palavrasReservadas.put("leln", 55);
		this.palavrasReservadas.put("palavra", 56);
		this.palavrasReservadas.put("entao", 57);
		this.palavrasReservadas.put("ate", 58);
		this.palavrasReservadas.put("var", 59);
		this.palavrasReservadas.put("enquanto", 60);
		this.palavrasReservadas.put("escreveln", 61);		
		this.palavrasReservadas.put("caracter", 62);
		this.palavrasReservadas.put("boolean", 63);
		this.palavrasReservadas.put("usar", 64);
		this.palavrasReservadas.put("verdade", 65);
		this.palavrasReservadas.put("falso", 66);
		this.palavrasReservadas.put("leln", 69);	
		

	}
	
	/**
	 */
	private void pontuacaoMapa() {
		this.marcasDePontuacao.put(",", 70);
		this.marcasDePontuacao.put(";", 71);
		this.marcasDePontuacao.put(":", 72);
		this.marcasDePontuacao.put(".", 73);
	}

	/**
	 * 
	 * @return o ultimo simbolo adicionado
	 */
	public String getUltimoSimbolo() {
		return (String) listaDeSimbolos.get(listaDeSimbolos.size() - 1).getSimbolo();
	}

	/**
	 * 
	 * @param simbolo
	 * @return
	 */
	public boolean ehPossivelOperador(String simbolo) {
		for (String symbol : operadores.keySet()) {
			if (symbol.startsWith(simbolo)) {
				return true;
			}
		}
		return false;
	}
}
